package com.xrh.xdemo.service;

import javax.validation.Validation;
import javax.validation.ValidatorFactory;

import org.hibernate.validator.HibernateValidator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.xrh.xdemo.service.interceptors.LoginInterceptor;
import com.xrh.xdemo.service.xss.XssJacksonDeserializer;

@Configuration
public class AppConfig implements WebMvcConfigurer {
		
	@Bean
    public ObjectMapper serializingObjectMapper() {
		
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.enable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        objectMapper.registerModule(new JavaTimeModule());
        
        /*解决长整形 , js精度问题*/
        SimpleModule simpleModule = new SimpleModule();
        simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
        simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
        
        //防攻击XSS序列化
//        simpleModule.addSerializer(String.class, new XssJacksonSerializer());  //向前端发送不需要编码
        simpleModule.addDeserializer(String.class, new XssJacksonDeserializer());
        
        //json属性忽略
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES , false);
        
        objectMapper.registerModule(simpleModule);
        
        return objectMapper;
    }
	
	 /**
     * 设置这个才没有分页问题 (新版本的不是这么配置的)
     */
	 @Bean
    public PaginationInterceptor paginationInterceptor(){
        return new PaginationInterceptor();
    }
	
	/**
	 * @function 允许跨域
	 * @author 肖荣辉
	 * @date 2020年11月3日
	*/
	@Bean  
    public CorsFilter corsFilter() {  
		
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();  
        
        CorsConfiguration corsConfiguration = new CorsConfiguration();  
        
        // 允许任何域名使用
        corsConfiguration.addAllowedOrigin("*"); 
        
        //允许任何头
        corsConfiguration.addAllowedHeader("*"); 
         
        //允许任何方法（post、get等） 
        corsConfiguration.addAllowedMethod("*");
        
        source.registerCorsConfiguration("/**" , corsConfiguration); 
        
        return new CorsFilter(source);  
    }  
	
	/**
	 * @function 校验发现第一个参数错误 , 即返回
	 * @author 肖荣辉
	 * @date 2021年8月11日
	*/
	@Bean
	public javax.validation.Validator validator(){
		ValidatorFactory validatorFactory = (ValidatorFactory) Validation.byProvider( HibernateValidator.class)
		.configure()
		.addProperty("hibernate.validator.fail_fast", "true")
		.buildValidatorFactory();
		return validatorFactory.getValidator();
	}
	

    /**
     * @function 加上这个bean,@version注解才有用,以支持乐观锁
     * @author 肖荣辉
     * @date 2021年12月10日
     */
    @Bean
    public OptimisticLockerInterceptor optimisticLockerInterceptor() {
        return new OptimisticLockerInterceptor();
    }	
    
    /**
	 * @function 登录不过滤的路径, 不需要加项目名
	 * @author 肖荣辉
	 * @date 2020年11月3日
	*/
	 private static final String[] EXCLUDE_PATHS = new String[] {
		
		 //静态资源	 
		"/TFUI/**" , "/views/**" , "/zui/**" , "/js/**" ,
		
		//swagger相关静态资源
		"swagger-ui.html" , "/swagger-resources/**" , "/swagger-resources" , "/v2/**" ,
		
		//knife4j
		"/doc.html" , "/webjars/**",
		
		//接口
		 "/login/login"  , "/login/needShowLoginValidCode" , "/login/downLoadLoginErrorValidCode",
		 
		 "/file/downLoadWordPng"
		
	 };
	 
	 /**
	 * @function 拦截器设置
	 * @author 肖荣辉
	 * @date 2020年11月3日
	*/
	public void addInterceptors(InterceptorRegistry registry) {
		registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/**").excludePathPatterns(EXCLUDE_PATHS);
	}

}
